package com.gome.extract;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.Vector;

import com.gome.extract.common.GlobalUtils;

class Node extends GlobalUtils
{
	public String _tag = "";
	
	public Node(){}
	public Node(String tag)
	{
		_tag = tag;
	}
}

class SNode
{
	public String mCss = "";
	public String mID = "";
	public Stack<Node> mSNode = new Stack<Node>();
	public SNode(String css, String id)
	{
		mCss = css;
		mID = id;
	}
	public void add(Node n)
	{
		mSNode.add(n);
	}
}

public class HTMLScanner extends GlobalUtils
{
    private static String mDictName = "";
    private HashMap<String, Integer> mHashDict = new HashMap<String, Integer>();
    private HashDict mDict = null;
    public HTMLScanner()
    {
    }
    
    public HTMLScanner(String dictName)
    {
    	mDictName = dictName;
    	mDict = new HashDict(dictName);
    }
    
	public String getTag(String input, int start)
	{
		int len = input.length();
		if(len<1)
			return "";
		StringBuffer sb = new StringBuffer();
		for(int i=start; i<len; ++i)
		{
			if(input.charAt(i)==' ' || input.charAt(i)=='>')
				break;
			sb.append(input.charAt(i));
		}
		return sb.toString();
	}
	
	public String getValue(String input, int start)
	{
		int len = input.length();
		if(len<1)
			return "";
		StringBuffer sb = new StringBuffer();
		for(int i=start; i<len; ++i)
		{
			if(input.charAt(i)=='<')
				break;

			sb.append(input.charAt(i));
		}
	
		return sb.toString();
	}
	
	public String getStr(String input, int start)
	{
		int len = input.length();
		if(len<1)
			return "";
		
		StringBuffer sb = new StringBuffer();
		boolean b = false;
		for(int i=start; i<len; ++i)
		{
			if(input.charAt(i)=='"' && !b)
			{
				b = true;
				continue;
			}
			if(input.charAt(i)=='"' && b)
			{
				break;
			}
			if(b)
			{
				sb.append(input.charAt(i));
			}
		}
		
		return sb.toString();
	}
	
	public String scan(String input)
	{	
		Stack<SNode> ss = new Stack<SNode>();
		HashMap<String, Vector<String> > mapResult = new HashMap<String, Vector<String> >();
		Vector<String> v = new Vector<String>();
		
		String cls = "";
		String id = "";
		String href = "";
		String tag = "";
		String src = "";
		String value = "";
		String url = "";
		int i=0;
		int len = input.length();
		while (i<len)
		{
			if(input.charAt(i)==' ' || input.charAt(i)=='\t')
			{
				i+=1;
				continue;
			}
			if(input.charAt(i)=='<' && i+1<len && input.charAt(i+1)=='!')
			{
				while(input.charAt(i)!='>')
				{
					++i;
				}
			}
			
			if(i+1<len && input.charAt(i)=='<' && input.charAt(i+1)!='/')
			{
				i += 1;
				tag = getTag(input, i);
				i += tag.length();
//				if(tag.equals("script"))
//				{
//					while(i<len)
//					{
//						if(input.charAt(i)=='s' && input.charAt(i+1)=='c' && input.charAt(i+2)=='r' && input.charAt(i+3)=='i' && input.charAt(i+4)=='p' && input.charAt(i+5)=='t')
//						{
//							break;
//						}
//						++i;
//					}
//					i += 6;
//				}
				while(i+1<len && input.charAt(i)!='>')
				{
					if(i+1<len  && input.charAt(i)==' ' && input.charAt(i+1)==' ')
					{
						i += 1;
						continue;
					}	
					if(i+2<len 
						&& (input.charAt(i)=='i'||(char)(input.charAt(i)+32)=='i') 
						&& (input.charAt(i+1)=='d'||(char)(input.charAt(i)+32)=='d') 
						&& input.charAt(i+2)=='=')
					{
						i += 3;
						id =  getStr(input, i);
//						print("id=" + id);
						i += id.length();					
					}
//					if(i+3<len && input.charAt(i)=='s' && input.charAt(i+1)=='r' && input.charAt(i+2)=='c' && input.charAt(i+3)=='=')
//					{
//						i += 4;
//						src =  getStr(input, i);
//						print("src=" + src);
//						i += src.length();
//					}
//					if(i+4<len && input.charAt(i)=='h' && input.charAt(i+1)=='r' && input.charAt(i+2)=='e' && input.charAt(i+3)=='f' && input.charAt(i+4)=='=' )
//					{
//						i += 5;
//						href = getStr(input, i);
//						print("href=" + href);
//						i+=href.length();
//					}
					if(i+5<len 
						&& input.charAt(i-1)=='"' 
						&& (input.charAt(i)=='h'  ||(char)(input.charAt(i)+32)=='h')
						&& (input.charAt(i+1)=='t'||(char)(input.charAt(i+1)+32)=='t')
						&& (input.charAt(i+2)=='t'||(char)(input.charAt(i+2)+32)=='t')
						&& (input.charAt(i+3)=='p'||(char)(input.charAt(i+3)+32)=='p')
						&& input.charAt(i+4)==':' && input.charAt(i+5)=='/')
					{
						url = getStr(input, i-1);
						i += url.length();
//						print(url);
					}
					if(i+5<len 
						&& (input.charAt(i)=='c'  ||(char)(input.charAt(i)+32)=='c') 
						&& (input.charAt(i+1)=='l'||(char)(input.charAt(i+1)+32)=='l') 
						&& (input.charAt(i+2)=='a'||(char)(input.charAt(i+2)+32)=='a') 
						&& (input.charAt(i+3)=='s'||(char)(input.charAt(i+3)+32)=='s')
						&& (input.charAt(i+4)=='s'||(char)(input.charAt(i+4)+32)=='s') 
						&& input.charAt(i+5)=='=')
					{
						i += 6;
						cls =  getStr(input, i);
//						print("class=" + cls);
						i += cls.length();					
					}
					i += 1;
				}

				cls = trimValue(cls);
				
				if(cls.length()!=0)
				{
					cls = cls.toLowerCase().split(" ")[0];
					ss.add(new SNode(cls, id));
				}
				
				if(ss.size()!=0)
				{
					if(url.indexOf("http")!=-1)
					{
						Node n = new Node(tag);
						ss.peek().mSNode.add(n);
						
						StringBuffer k = new StringBuffer();
						int t = 0;
						for(int j=ss.size()-1; j>=0 && t<3; --j, ++t)
						{
							if(t==2 || j==0)
							{
								k.append(ss.elementAt(j).mCss);
								break;
							}
							k.append(ss.elementAt(j).mCss + CON);
//							k.append(ss.elementAt(j).mCss);
						}
						String key = k.toString();
						if(key.length()!=0)
						{
							if(mapResult.containsKey(key))
							{
								mapResult.get(key).add(url);
							}
							else
							{
								Vector<String>v1 = new Vector<String>();
								v1.add(url);
								mapResult.put(key, v1);	
							}
						}
					}
					else
					{
						Node n = new Node(tag);
						ss.peek().mSNode.add(n);
					}
				}
				url = "";
				cls = "";
				id = "";
			}
			
			if(i<len && input.charAt(i)=='>')
			{
				i += 1;
				value = getValue(input, i);

				i += value.length();
				value = trimValue(value);
				if(value.length()!=0)
				{
					StringBuffer k = new StringBuffer();
					int t = 0;
					for(int j=ss.size()-1; j>=0 && t<3; --j, ++t)
					{
						if(t==2 || j==0)
						{
							k.append(ss.elementAt(j).mCss);
							break;
						}
						k.append(ss.elementAt(j).mCss + CON);
//						k.append(ss.elementAt(j).mCss);
					}
					String key = k.toString();
					if(key.length()!=0)
					{
						if(mapResult.containsKey(key))
						{
							mapResult.get(key).add(value);
						}
						else
						{
							Vector<String>v1 = new Vector<String>();
							v1.add(value);
							mapResult.put(key, v1);	
						}
					}
				}
			}	
			if(i+1<len && input.charAt(i)=='<' && input.charAt(i+1)=='/')
			{
				i += 2;
				tag = getTag(input, i);
				if(ss.size()!=0)
				{				
					while(ss.peek().mSNode.size()!=0 && ss.peek().mSNode.peek()._tag.equals(tag)==false)
					{
						ss.peek().mSNode.pop();
					}
									
					if(ss.peek().mSNode.size()!=0)
					{
						ss.peek().mSNode.pop();
					}
					if(ss.peek().mSNode.size()==0)
					{
						ss.pop();
					}
				}
				
				i += tag.length();
				while(i<len && input.charAt(i)!='>')
				{
					i += 1;
				}
			}
			
			tag = "";
			value = "";
		}
		return print(mapResult);	
	}
	
	public String print(HashMap<String, Vector<String> > mapResult)
	{	
		
		String s = "";
		int id = 0;
		HashMap<Integer, String> hs = new HashMap<Integer, String>();
		for(Entry<String, Vector<String>> entry : mapResult.entrySet())
		{
			String k = entry.getKey();			
			id = mDict.add(k);
			Vector<String>v = entry.getValue();
			StringBuffer sb = new StringBuffer();
			for(int j=0; j<v.size(); ++j)
			{
				s = trimValue(v.elementAt(j));
				if(s.length()!=0)
				{
					if(j==v.size()-1)
					{
						sb.append(s);
						break;
					}
					sb.append(s + CON);
				}
			}
			hs.put(id, sb.toString());
//			sb.append(SEP);
//			print(k);
//			if(sb.toString().length()!=0)
//			{
//				print(k);
//				print(sb.toString());
//			}
		}		
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<mDict.size(); ++i)
		{
			if(hs.containsKey(i))
			{
				sb.append(hs.get(i) + SEP);
			}
			else
			{
				sb.append("null" + SEP);
			}
		}
	
		return sb.toString();
	}
	
	public HashMap<String, Vector<String>> test(String input)
	{	
		Stack<SNode> ss = new Stack<SNode>();
		HashMap<String, Vector<String> > mapResult = new HashMap<String, Vector<String> >();
		Vector<String> v = new Vector<String>();
		
		String cls = "";
		String id = "";
		String href = "";
		String tag = "";
		String src = "";
		String value = "";
		String url = "";
		int i=0;
		int len = input.length();
		while (i<len)
		{
			if(input.charAt(i)==' ' || input.charAt(i)=='\t')
			{
				i+=1;
				continue;
			}
			if(input.charAt(i)=='<' && i+1<len && input.charAt(i+1)=='!')
			{
				while(input.charAt(i)!='>')
				{
					++i;
				}
			}
			
			if(i+1<len && input.charAt(i)=='<' && input.charAt(i+1)!='/')
			{
				i += 1;
				tag = getTag(input, i);
				i += tag.length();
//				if(tag.equals("script"))
//				{
//					while(i<len)
//					{
//						if(input.charAt(i)=='s' && input.charAt(i+1)=='c' && input.charAt(i+2)=='r' && input.charAt(i+3)=='i' && input.charAt(i+4)=='p' && input.charAt(i+5)=='t')
//						{
//							break;
//						}
//						++i;
//					}
//					i += 6;
//				}
				while(i+1<len && input.charAt(i)!='>')
				{
					if(i+1<len  && input.charAt(i)==' ' && input.charAt(i+1)==' ')
					{
						i += 1;
						continue;
					}	
					if(i+2<len 
						&& (input.charAt(i)=='i'||(char)(input.charAt(i)+32)=='i') 
						&& (input.charAt(i+1)=='d'||(char)(input.charAt(i)+32)=='d') 
						&& input.charAt(i+2)=='=')
					{
						i += 3;
						id =  getStr(input, i);
//						print("id=" + id);
						i += id.length();					
					}
//					if(i+3<len && input.charAt(i)=='s' && input.charAt(i+1)=='r' && input.charAt(i+2)=='c' && input.charAt(i+3)=='=')
//					{
//						i += 4;
//						src =  getStr(input, i);
//						print("src=" + src);
//						i += src.length();
//					}
//					if(i+4<len && input.charAt(i)=='h' && input.charAt(i+1)=='r' && input.charAt(i+2)=='e' && input.charAt(i+3)=='f' && input.charAt(i+4)=='=' )
//					{
//						i += 5;
//						href = getStr(input, i);
//						print("href=" + href);
//						i+=href.length();
//					}
					if(i+5<len 
						&& input.charAt(i-1)=='"' 
						&& (input.charAt(i)=='h'  ||(char)(input.charAt(i)+32)=='h')
						&& (input.charAt(i+1)=='t'||(char)(input.charAt(i+1)+32)=='t')
						&& (input.charAt(i+2)=='t'||(char)(input.charAt(i+2)+32)=='t')
						&& (input.charAt(i+3)=='p'||(char)(input.charAt(i+3)+32)=='p')
						&& input.charAt(i+4)==':' && input.charAt(i+5)=='/')
					{
						url = getStr(input, i-1);
						i += url.length();
//						print(url);
					}
					if(i+5<len 
						&& (input.charAt(i)=='c'  ||(char)(input.charAt(i)+32)=='c') 
						&& (input.charAt(i+1)=='l'||(char)(input.charAt(i+1)+32)=='l') 
						&& (input.charAt(i+2)=='a'||(char)(input.charAt(i+2)+32)=='a') 
						&& (input.charAt(i+3)=='s'||(char)(input.charAt(i+3)+32)=='s')
						&& (input.charAt(i+4)=='s'||(char)(input.charAt(i+4)+32)=='s') 
						&& input.charAt(i+5)=='=')
					{
						i += 6;
						cls =  getStr(input, i);
//						print("class=" + cls);
						i += cls.length();					
					}
					i += 1;
				}

				if(cls.length()!=0 || id.length()!=0)
				{	
					cls = cls.toLowerCase().split(" ")[0];
					ss.add(new SNode(cls, id));
				}
							
				if(ss.size()!=0)
				{
					if(url.indexOf("http")!=-1)
					{
						Node n = new Node(tag);
						ss.peek().mSNode.add(n);
						
						StringBuffer k = new StringBuffer();
						int t = 0;
						for(int j=ss.size()-1; j>=0 && t<3; --j, ++t)
						{
							if(t==2 || j==0)
							{
								k.append(ss.elementAt(j).mCss);
								break;
							}
							k.append(ss.elementAt(j).mCss + CON);
//							k.append(ss.elementAt(j).mCss);
						}
						String key = k.toString();
						if(key.length()!=0)
						{
							if(mapResult.containsKey(key))
							{
								mapResult.get(key).add(url);
							}
							else
							{
								Vector<String>v1 = new Vector<String>();
								v1.add(url);
								mapResult.put(key, v1);	
							}
						}
					}
					else
					{
						Node n = new Node(tag);
						ss.peek().mSNode.add(n);
					}
				}
				url = "";
				cls = "";
				id = "";
			}
			
			if(i<len && input.charAt(i)=='>')
			{
				i += 1;
				value = getValue(input, i);

				i += value.length();
				value = trimValue(value);
				if(value.length()!=0)
				{
					StringBuffer k = new StringBuffer();
					int t = 0;
					for(int j=ss.size()-1; j>=0 && t<3; --j, ++t)
					{
						if(t==2 || j==0)
						{
							k.append(ss.elementAt(j).mCss);
							break;
						}
						k.append(ss.elementAt(j).mCss + CON);
//						k.append(ss.elementAt(j).mCss);
					}
					String key = k.toString();
					if(key.length()!=0)
					{
						if(mapResult.containsKey(key))
						{
							mapResult.get(key).add(value);
						}
						else
						{
							Vector<String>v1 = new Vector<String>();
							v1.add(value);
							mapResult.put(key, v1);	
						}
					}
				}
			}	
			if(i+1<len && input.charAt(i)=='<' && input.charAt(i+1)=='/')
			{
				i += 2;
				tag = getTag(input, i);
				if(ss.size()!=0)
				{				
					while(ss.peek().mSNode.size()!=0 && ss.peek().mSNode.peek()._tag.equals(tag)==false)
					{
						ss.peek().mSNode.pop();
					}
									
					if(ss.peek().mSNode.size()!=0)
					{
						ss.peek().mSNode.pop();
					}
					if(ss.peek().mSNode.size()==0)
					{
						ss.pop();
					}
				}
				
				i += tag.length();
				while(i<len && input.charAt(i)!='>')
				{
					i += 1;
				}
			}
			
			tag = "";
			value = "";
		}
		return  mapResult;	
	}
	
	public void writeDict()
    {
    	mDict.write();
    }
}



















